/**
 * @desc  判断是否为身份证号
 * @param  {String|Number} str 
 * @return {Boolean}
 */
function isIdCard(str) {
   const val = str;
   const city = {
     11: "北京",
     12: "天津",
     13: "河北",
     14: "山西",
     15: "内蒙古",
     21: "辽宁",
     22: "吉林",
     23: "黑龙江",
     31: "上海",
     32: "江苏",
     33: "浙江",
     34: "安徽",
     35: "福建",
     36: "江西",
     37: "山东",
     41: "河南",
     42: "湖北",
     43: "湖南",
     44: "广东",
     45: "广西",
     46: "海南",
     50: "重庆",
     51: "四川",
     52: "贵州",
     53: "云南",
     54: "西藏",
     61: "陕西",
     62: "甘肃",
     63: "青海",
     64: "宁夏",
     65: "新疆",
     71: "台湾",
     81: "香港",
     82: "澳门",
     91: "国外"
   };
   // 长度校验 15位号码应全为数字 18位号码末位可以为数字或X
   if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(val))) {
     return val === null || val === "" ? null : "身份证号长度格式错误";
   }
   // 地址校验
   if (!city[val.substr(0, 2)]) {
     return val === null || val === "" ? null : "身份证号地址编码错误";
   }
   // 位校验
   if (val.length === 18) {
     const arrData = val.match(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X|x)$/);
     const {
       year,
       month,
       day
     } = {
         year: arrData[2],
         month: arrData[3],
         day: arrData[4]
       };
     const birthday = new Date(year + "/" + month + "/" + day);
     const now = new Date();
     const nowYear = now.getFullYear();
     const bGoodDay = (birthday.getFullYear() === Number(year)) && ((birthday.getMonth() + 1) === Number(
       month)) && (birthday.getDate() === Number(day));
     // 年月日是否合理
     if (!bGoodDay) {
       return val === null || val === "" ? null : "身份证号出生日期不合规";
     } else {
       // 判断年份的范围（0岁到100岁之间)
       const time = Number(nowYear) - Number(year);
       if (!(time >= 0 && time <= 100)) {
         return val === null || val === "" ? null : "身份证号出生日期不合规";
       }
     }
   
     const list = val.split("");
     // 加权因子
     const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
     // 校验位
     const parity = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
     let {
       sum,
       ai,
       wi
     } = {
         sum: 0,
         ai: 0,
         wi: 0
       };
     for (let i = 0; i < 17; i++) {
       ai = list[i];
       wi = factor[i];
       sum += ai * wi;
     }
     if (parity[sum % 11] !== list[17]) {
       return val === null || val === "" ? null : "身份证号格式错误";
     }
   }
	 
	 return true;
}

export { isIdCard };